<template>
    <div class="draw-div">

        <canvas ref="dialCanvas" class="dial-canvas"
                width="15rem" height="15rem"
                :style="{left:dialLeft+'px',width:dialWidth+'px',height:dialHeight+'px'}"></canvas>
        <canvas ref="waveCanvas" class="wave-canvas"
                width="14.99rem" height="14.99rem"
                :style="{left:waveLeft+'px',top:waveTop+'px',width:waveWidth+'px',height:waveHeight+'px'}"></canvas>

    </div>
</template>

<script>
    import SimplexNoise from 'simplex-noise'

    export default {
        name: "dial",
        props: {
            //数值
            val: {
                default: 0
            },
            titleName: {
                default: ''
            },
            //单位
            dialUnit: {
                default: ''
            },
            //图表进度上限
            limit: {
                default: 100
            },
            //图表描述
            dialDetail: {
                default: ''
            },
            //图表进度步长
            step: {
                default: 1
            },
            //设备是否在线
            onLine: {
                default: '0'
            }
        },
        data() {
            return {
                //仪表片宽度
                dialWidth: 215,
                //仪表盘高度
                dialHeight: 215,

                //波浪宽度
                waveWidth: 201,
                //波浪高度
                waveHeight: 201,

                //仪表盘左定位
                dialLeft: 0,
                //仪表盘右定位
                waveLeft: 0,
                //波浪上定位
                waveTop: 0
            }
        },
        mounted() {
            let that = this;
            that.stopWave();
            that.initDraw();
            that.initDialPosition();
            that.initWavePosition();
            that.initProcess(that.val, '当前数值', that.dialDetail, '实时浓度', that.limit, that.step);
            that.initWave(that.val);
        },
        watch: {
            val(val, oldVal) {
                console.log(val);
                console.log(oldVal);
            }
        },
        methods: {
            getFontSize() {
                return Number(String(document.documentElement.style.fontSize).replace('px', ''));
            },
            initDraw() {
                let that = this;
                //初始化表盘
                that.dialWidth = that.$refs.dialCanvas.width * that.getFontSize();
                that.dialHeight = that.$refs.dialCanvas.height * that.getFontSize();
                //初始化波浪
                that.waveWidth = that.$refs.waveCanvas.width * that.getFontSize();
                that.waveHeight = that.$refs.waveCanvas.height * that.getFontSize();
            },
            //初始化表盘位置
            initDialPosition() {
                let that = this;
                that.dialLeft = window.innerWidth / 2 - (that.dialWidth / 2);
            },
            //初始化波浪位置
            initWavePosition() {
                let that = this;
                that.waveLeft = window.innerWidth / 2 - (that.waveWidth / 2);
                that.waveTop = that.dialHeight / 2 - (that.waveHeight / 2);
            },
            //绘制蓝色外圈
            blueCircle(n, centerX, centerY, rad) {
                let that = this;
                that.$dial.ctx.save();
                that.$dial.ctx.strokeStyle = "#8E55E9"; //设置描边样式
                that.$dial.ctx.lineWidth = 6; //设置线宽
                that.$dial.ctx.beginPath(); //路径开始
                that.$dial.ctx.arc(centerX, centerY, 103.5, Math.PI / 2, Math.PI / 2 + n * rad, false); //用于绘制圆弧context.arc(x坐标，y坐标，半径，起始角度，终止角度，顺时针/逆时针)
                that.$dial.ctx.stroke(); //绘制
                that.$dial.ctx.closePath(); //路径结束
                that.$dial.ctx.restore();
            },
            whiteCircle(centerX, centerY) {
                let that = this;
                that.$dial.ctx.save();
                that.$dial.ctx.beginPath();
                that.$dial.ctx.lineWidth = 6; //设置线宽
                that.$dial.ctx.strokeStyle = "#81CBFF";
                that.$dial.ctx.arc(centerX, centerY, 103.5, 0, Math.PI * 2, false);
                that.$dial.ctx.strokeStyle = "#81CBFF"
                that.$dial.ctx.stroke()
                that.$dial.ctx.fillStyle = "rgba(0,0,0,0)";
                that.$dial.ctx.fill()
                that.$dial.ctx.closePath();
                that.$dial.ctx.restore();
            },
            //百分比文字绘制
            text(n, centerX, centerY, title, dataDetail, dataInfo) {
                let that = this;
                that.$dial.ctx.save(); //save和restore可以保证样式属性只运用于该段canvas元素
                that.$dial.ctx.beginPath();
                that.$dial.ctx.strokeStyle = "#fff"; //设置描边样式
                that.$dial.ctx.fillStyle = that.formatColor(dataDetail, "#3198FC"); //字体填充颜色
                that.$dial.ctx.font = "50px Arial"; //设置字体大小和字体
                let x = centerX - 55;
                let y = centerY + 8;
                //处理小数
                if (String(n).indexOf(".") !== -1) {
                    x = centerX - 62;
                    //保留3位小数
                    n = n.toFixed(3);
                }
                //大于一
                else if (n < 10) {
                    x = centerX - 12;
                } else if (n >= 10 && n < 100) {
                    x = centerX - 21;
                } else if (n >= 100 && n < 1000) {
                    x = centerX - 41;
                } else if (n >= 1000) {
                    x = centerX - 56;
                }
                //绘制字体，并且指定位置 （表盘中的数值）
                that.$dial.ctx.fillText(n, x, y);
                that.$dial.ctx.stroke(); //执行绘制
                that.$dial.ctx.closePath();

                //设置表盘title
                x = centerX - 45;
                y = centerY - 55;
                that.$dial.ctx.font = "17px Arial"; //设置字体大小和字体
                that.$dial.ctx.fillStyle = "#010b13"; //字体填充颜色
                if (title.length === 4) {
                    x = centerX - 33;
                }
                that.$dial.ctx.fillText(title, x, y);
                that.$dial.ctx.stroke(); //执行绘制
                that.$dial.ctx.closePath();

                //数值描述（表盘中描述）
                x = centerX - 69;
                y = centerY + 39;
                if (dataDetail.length === 1) {  //一个字
                    x = centerX - 10;
                } else if (dataDetail.length === 2) { //两个字
                    x = centerX - 15;
                } else if (dataDetail.length === 3) { //三个字
                    x = centerX - 21;
                } else if (dataDetail.length === 4) { //四个字
                    x = centerX - 27;
                }
                that.$dial.ctx.font = "16px Arial"; //设置字体大小和字体
                //处理颜色
                that.$dial.ctx.fillStyle = that.formatColor(dataDetail, "#010b13"); //字体填充颜色
                that.$dial.ctx.fillText(dataDetail, x, y);
                that.$dial.ctx.stroke(); //执行绘制
                that.$dial.ctx.closePath();

                //数值明细
                x = centerX - 20;
                y = centerY + 62;
                that.$dial.ctx.font = "10px Arial"; //设置字体大小和字体
                that.$dial.ctx.fillStyle = "#010b13"; //字体填充颜色
                that.$dial.ctx.fillText(dataInfo, x, y);
                x = centerX - 35;
                y = centerY + 71;
                that.$dial.ctx.fillText('-------------------------', x, y);
                x = centerX - 16;
                y = centerY + 80;
                that.$dial.ctx.fillText(that.dialUnit, x, y);
                that.$dial.ctx.stroke(); //执行绘制
                that.$dial.ctx.closePath();

                that.$dial.ctx.restore();
            },
            //格式化颜色
            formatColor(dataDetail, defColor) {
                if (dataDetail === '不合格') {
                    return "red"; //字体填充颜色
                } else if (dataDetail === '优') {
                    return "#45E400"; //字体填充颜色
                } else if (dataDetail === '良') {
                    return "#FDFF00"; //字体填充颜色
                } else if (dataDetail === '轻度污染') {
                    return "#F67E02"; //字体填充颜色
                } else if (dataDetail === '中度污染') {
                    return "#F40103"; //字体填充颜色
                } else if (dataDetail === '重度污染') {
                    return "#99004C"; //字体填充颜色
                } else if (dataDetail === '严重污染') {
                    return "#7E0023"; //字体填充颜色
                } else {
                    return defColor; //字体填充颜色
                }
            },
            initProcess(process, title, dataDetail, dataInfo, limit, step) {
                let that = this;
                that.$dial.canvas = that.$refs.dialCanvas;
                that.$dial.canvas.width = 215;
                that.$dial.canvas.height = 215;
                that.$dial.ctx = that.$dial.canvas.getContext('2d');
                let centerX = that.$dial.canvas.width / 2;   //Canvas中心点x轴坐标
                let centerY = that.$dial.canvas.height / 2;  //Canvas中心点y轴坐标
                let rad = Math.PI * 2 / limit; //将360度分成100份，那么每一份就是rad度
                //动画
                // let speed = 0;
                // let timeout = setInterval(function () {
                //   that.$dial.ctx.clearRect(0, 0, that.$dial.canvas.width, that.$dial.canvas.height);
                //   that.whiteCircle(centerX, centerY);
                //   that.text(speed, centerX, centerY, title, dataDetail, dataInfo);
                //   that.blueCircle(speed, centerX, centerY, rad);
                //   if (speed >= process) {
                //     clearInterval(timeout)
                //     that.stopWave();
                //   }
                //   speed += step;
                // }, 10);

                let speed = process;
                that.$dial.ctx.clearRect(0, 0, that.$dial.canvas.width, that.$dial.canvas.height);
                that.whiteCircle(centerX, centerY);
                that.text(speed, centerX, centerY, title, dataDetail, dataInfo);
                that.blueCircle(speed, centerX, centerY, rad);
                console.log(step)
            },
            //初始化波浪
            initWave(process) {
                console.log('初始化波浪进度->' + process)
                let that = this;
                that.$wave.canvas = that.$refs.waveCanvas;
                that.$wave.canvas.width = 215;
                that.$wave.canvas.height = 215;
                that.$wave.ctx = that.$wave.canvas.getContext('2d');
                that.$wave.simplex = new SimplexNoise();
                that.startWave(process)
                //设备在线才会有动画
                if (that.onLine === '0') {
                    that.stopWave();
                }
            },
            waveReset() {
                let that = this;
                that.$wave.w = that.$wave.canvas.width;
                that.$wave.h = that.$wave.canvas.height;
                that.$wave.cx = that.$wave.w / 2;
                that.$wave.cy = that.$wave.h / 2;

                that.$wave.count = Math.floor(that.$wave.w / 10); // Wave frequency
                that.$wave.xoff = 0;
                that.$wave.xinc = 0.05;
                that.$wave.yoff = 0;
                that.$wave.yinc = 0.002; // Speed
                that.$wave.goff = 0;
                that.$wave.ginc = 0;
                that.$wave.y = that.$wave.h * 0.65;
                that.$wave.length = that.$wave.w + 0;
                that.$wave.amp = 18; // Wave height
            },
            //波浪
            wave(color, amp, height, comp) {
                let that = this;
                that.$wave.ctx.beginPath();
                for (let i = 0; i <= that.$wave.count; i++) {
                    that.$wave.xoff += that.$wave.xinc;
                    let x = that.$wave.cx - that.$wave.length / 2 + that.$wave.length / that.$wave.count * i;
                    let y = height + that.$wave.simplex.noise2D(that.$wave.xoff, that.$wave.yoff) * amp;
                    that.$wave.ctx[i === 0 ? 'moveTo' : 'lineTo'](x, y);
                }

                that.$wave.ctx.lineTo(that.$wave.w, -that.$wave.h); // -$.h - Vertically reflection
                that.$wave.ctx.lineTo(0, -that.$wave.h); // -$.h - Vertically reflection
                that.$wave.ctx.closePath();
                that.$wave.ctx.fillStyle = color;
                if (comp) {
                    that.$wave.ctx.globalCompositeOperation = comp;
                }
                that.$wave.ctx.fill();
            },
            loop() {
                let that = this;
                that.$wave.waveloopnumber = requestAnimationFrame(that.loop);
                that.$wave.ctx.clearRect(0, 0, that.$wave.w, that.$wave.h);
                that.$wave.xoff = 0;

                that.$wave.ctx.fillStyle = "#ccdef6";
                that.$wave.ctx.fillRect(0, 0, that.$wave.w, that.$wave.h);

                that.wave("#48bbe0", 50, that.$wave.h * .5, "screen");
                that.wave("#94b2c6", 50, that.$wave.h * .5, "screen");
                that.wave("#FFFFFF", 50, that.$wave.h * .5, "screen");

                // that.$dial.ctx.fillStyle = "#d0c4c3";

                that.$wave.ctx.globalCompositeOperation = "darken";

                that.$wave.ctx.fillRect(0, 0, that.$wave.w, that.$wave.h);

                that.$wave.yoff += that.$wave.yinc;
                that.$wave.goff += that.$wave.ginc;
            },
            startWave() {
                let that = this;
                that.waveReset();
                that.loop()
            },
            stopWave() {
                let that = this;
                cancelAnimationFrame(that.$wave.waveloopnumber);
            }
        },
    }
</script>

<style scoped>
    .draw-div {
        width: 100%;
        text-align: center;
        position: relative;
    }

    .dial-canvas {
        z-index: 10;
        position: absolute;
    }

    .wave-canvas {
        z-index: 9;
        position: absolute;
        text-align: center;
        border-radius: 50%;
    }
</style>
